package com.yanqu.road.server.gameplayer.module.activity.pixiu;

import com.yanqu.road.dao.impl.activity.pixiu.PiXiuUserDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.pixiu.PiXiuUserData;
import com.yanqu.road.entity.activity.pixiu.config.PiXiuAmuseInfo;
import com.yanqu.road.entity.log.pixiu.LogPiXiuTap;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.pb.activity.PiXiuProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.pixiu.PiXiuActivityMgr;
import com.yanqu.road.server.manger.activity.pixiu.PiXiuConfig;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.util.Random;

public class PiXiuModule extends GeneralModule {

    private PiXiuUserData userData;

    public PiXiuModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        return true;
    }

    @Override
    public boolean afterLoadData() {
        ActivityInfo activityInfo = PiXiuActivityMgr.getActivityInfo();
        if(ActivityMgr.activityInShowTime(activityInfo)) {
            userData = new PiXiuUserDataDaoImpl().getPiXiuUserData(activityInfo.getActivityId(), player.getUserId());
        }
        return true;
    }

    @Override
    public boolean saveData() {
        if(userData != null){
            if(userData.isInsertOption()){
                new PiXiuUserDataDaoImpl().add(userData);
            }else if(userData.isUpdateOption()){
                new PiXiuUserDataDaoImpl().update(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        activityReload();
    }

    public void activityReload() {

        if (!SystemOpenMgr.systemOpen(player, eSystemId.PiXiuActivity.getValue())) {
            return;
        }

        PiXiuConfig config = PiXiuActivityMgr.getConfig();
        if(config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())){
            return;
        }

        syncConfig(config);

        initUserData(config);

        syncUserData(config);
    }

    private void syncUserData(PiXiuConfig config) {
        if(userData == null){
            return;
        }
        PiXiuProto.PiXiuUserDataSyncMsg.Builder builder = PiXiuProto.PiXiuUserDataSyncMsg.newBuilder();
        builder.setUserData(PiXiuActivityMgr.builder(userData));
        player.sendPacket(Protocol.U_PI_XIU_SYNC_DATA, builder);
    }

    private void syncConfig(PiXiuConfig config) {
        PiXiuProto.PiXiuConfigDataSyncMsg.Builder builder = PiXiuProto.PiXiuConfigDataSyncMsg.newBuilder();
        for (PiXiuAmuseInfo info : config.getAmuseInfoList()) {
            PiXiuProto.PiXiuAmuseTemp.Builder infoBuilder = PiXiuProto.PiXiuAmuseTemp.newBuilder();
            infoBuilder.setId(info.getId());
            infoBuilder.setItemId(info.getItemId());
            infoBuilder.setType(info.getType());
            infoBuilder.addAllItemNumList(info.getItemNumList());
            builder.addAmuse(infoBuilder);
        }
        player.sendPacket(Protocol.U_PI_XIU_SYNC_CONFIG, builder);
    }

    private synchronized void initUserData(PiXiuConfig config) {

        if(userData == null || userData.getActivityId() != config.getActivityId()){

            PiXiuUserData tempData = new PiXiuUserData();
            tempData.setUserId(player.getUserId());
            tempData.setActivityId(config.getActivityId());
            tempData.setInsertOption();
            userData = tempData;

        }
    }

    /**
     * 获取玩家数据
     */
    public int getData() {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        PiXiuProto.GetPiXiuUserDataRespMsg.Builder builder = PiXiuProto.GetPiXiuUserDataRespMsg.newBuilder();
        builder.setRet(0);
        builder.setUserData(PiXiuActivityMgr.builder(userData));
        player.sendPacket(Protocol.U_PI_XIU_SYNC_GET_DATA, builder);
        return 0;
    }

    /**
     * 领取累积奖励
     */
    public int getAllReward() {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        if(userData.getGetReward() == 1){
            return GameErrorCode.E_ACTIVITY_REWARD_IS_GET;
        }

        if(userData.getHeadReward() <= 0 || userData.getButtReward() <= 0){
            return GameErrorCode.E_PI_XIU_NO_SELECT_BIG_REWARD;
        }

        PiXiuConfig config = PiXiuActivityMgr.getConfig();
        if(config == null){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }

        //计算奖励
        Property all = PiXiuActivityMgr.getProperty(userData, config);

        userData.setGetReward(1);
        player.getModule(CurrencyModule.class).addCurrency(all, eLogMoneyType.PiXiu, eLogMoneyType.PiXiuRebateReward);

        PiXiuProto.PiXiuGetAllRewardRespMsg.Builder builder = PiXiuProto.PiXiuGetAllRewardRespMsg.newBuilder();
        builder.setRet(0);
        builder.setReward(PropertyHelper.parsePropertyToString(all));
        builder.setUserData(PiXiuActivityMgr.builder(userData));
        player.sendPacket(Protocol.U_PI_XIU_GET_ALL_REWARD, builder);
        return 0;
    }

    /**
     * 道具击打
     */
    public int tap() {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        if(userData.getHeadReward() <= 0 || userData.getButtReward() <= 0){
            return GameErrorCode.E_PI_XIU_NO_SELECT_BIG_REWARD;
        }

        PiXiuConfig config = PiXiuActivityMgr.getConfig();

        if(config == null){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }

        GoodsInfo goodsInfo = GoodsMgr.getGoodsById(config.getItemId());
        if(goodsInfo == null){
            return GameErrorCode.E_GOODS_NO_EXIST;
        }

        Random random = new Random();
        int idx = RandomHelper.getRandomIndexByWeight(config.getWeightList(), random);
        if(idx == -1){
            return GameErrorCode.E_GAME_ERROR;
        }
        int type = idx + 1;
        PiXiuAmuseInfo amuseInfo = null;
        if(type == 1){
            //脚
            amuseInfo = config.getPiXiuAmuseInfo(type, GameConfig.GAME_MONEY_INGOTS);
        }else if(type == 2){
            //头
            amuseInfo = config.getPiXiuAmuseInfo(type, userData.getHeadReward());
        }else if(type == 3){
            //臀
            amuseInfo = config.getPiXiuAmuseInfo(type, userData.getButtReward());
        }
        if(amuseInfo == null){
            return GameErrorCode.E_GAME_ERROR;
        }

        //扣道具
        Property consume = PropertyHelper.parseStringToProperty(config.getItemId() + "=1");
        if(!player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.PiXiu, eLogMoneyType.PiXiuTapConsume)){
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        int add;
        int min = amuseInfo.getItemNumList().get(0);
        int max = amuseInfo.getItemNumList().get(1);
        if(min == max){
            add = min;
        }else {
            add = min + random.nextInt(max - min + 1);
        }


        if(type == 1){
            //脚
            userData.setFootBase(add + userData.getFootBase());

        }else if(type == 2){
            //头
            userData.setHeadBase(add + userData.getHeadBase());

        }else if(type == 3){
            //臀
            userData.setButtBase(add + userData.getButtBase());

        }

        //喜悦值
        int addHappy = goodsInfo.getParamList().get(0).intValue();

        userData.setHappyValue(userData.getHappyValue() + addHappy);
        player.notifyListener(eGamePlayerEventType.PiXiuHappyValue.getValue(), userData.getHappyValue());

        //日志
        AutoLogMgr.add(new LogPiXiuTap(userData.getActivityId(), player.getUserId(), addHappy, userData.getHappyValue()));

        PiXiuProto.PiXiuGoodsTapRespMsg.Builder builder = PiXiuProto.PiXiuGoodsTapRespMsg.newBuilder();
        builder.setRet(0);
        builder.setUserData(PiXiuActivityMgr.builder(userData));
        builder.setPos(type);
        builder.setAdd(add);
        player.sendPacket(Protocol.U_PI_XIU_GOODS_TAP, builder);
        return 0;
    }

    /**
     * 选择奖励
     * @param reward1 头部奖励
     * @param reward2 臀部奖励
     */
    public int selectReward(int reward1, int reward2) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        //判断是否设置过
        if(userData.getHeadReward() > 0 || userData.getButtReward() > 0){
            return GameErrorCode.E_PI_XIU_HAD_SELECT_BIG_REWARD;
        }
        PiXiuConfig config = PiXiuActivityMgr.getConfig();
        //判断奖池是否有效
        if(config.getPiXiuAmuseInfo(2, reward1) == null ||
            config.getPiXiuAmuseInfo(3, reward2) == null){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }
        userData.setHeadReward(reward1);
        userData.setButtReward(reward2);

        PiXiuProto.PiXiuSelectRewardRespMsg.Builder builder = PiXiuProto.PiXiuSelectRewardRespMsg.newBuilder();
        builder.setRet(0);
        builder.setUserData(PiXiuActivityMgr.builder(userData));
        player.sendPacket(Protocol.U_PI_XIU_SELECT_REWARD, builder);
        return 0;
    }

    public void addUseToken(long useValue) {
        if(useValue <= 0){
            return;
        }
        if(userData == null){
            return;
        }
        PiXiuConfig config = PiXiuActivityMgr.getConfig();
        if(config == null){
            return;
        }
        //不在展示期+活动期
        if(!ActivityMgr.activityInTime(config.getActivityInfo()) && ActivityMgr.activityInShowPeriod(config.getActivityInfo())){
            return;
        }
        userData.setUseTokenNum(useValue + userData.getUseTokenNum());
        syncUserData(config);
    }
}
